#import "AppDelegate.h"
#import <WuKongBase/WuKongBase.h>
#import "WKMainTabController.h"
@import WuKongContacts;
#import <WuKongBase/WKSyncService.h>
#import "WKMeVC.h"
#import "SELUpdateAlert.h"
#import "WKServerNode.h"
#import "WKLoadingViewController.h"

// 原主域名默认配置
#define DEFAULT_SERVER_IP @"tgimapi.wmxxm.cn"
#define DEFAULT_HTTPS_ON YES
// 本地测试节点开启
#define LOCAL_TEST_NODES_NO NO

// 节点列表JSON地址
#define SERVER_NODE_URL @""
// 节点获取超时时间（2秒）
#define NODE_FETCH_TIMEOUT 2.0

// 本地测试节点JSON文件名
#define LOCAL_TEST_NODES_FILENAME @"test_servers"

@interface AppDelegate ()<UITabBarControllerDelegate>
@property(nonatomic,strong) WKConversationListVC *conversationList;
@property(nonatomic,strong) WKMeVC *meVC;
@property(nonatomic, strong) NSArray<WKServerNode *> *serverNodes; // 服务器节点列表
@property(nonatomic, copy) NSString *currentServerIP;           // 当前使用的服务器IP
@property(nonatomic, assign) BOOL currentHTTPSOn;               // 当前是否启用HTTPS
@property(nonatomic, strong) WKLoadingViewController *loadingVC;  // 加载界面
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 提前初始化窗口和根视图控制器，减少白屏时间
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    self.window.backgroundColor = [UIColor grayColor];
    
    // 使用加载界面作为初始根视图，显示品牌和加载状态
    self.loadingVC = [WKLoadingViewController new];
    self.window.rootViewController = self.loadingVC;
    [self.window makeKeyAndVisible];

    // 并行加载登录信息和初始化基础组件
    dispatch_group_t initGroup = dispatch_group_create();
    
    // 加载登录信息
    dispatch_group_enter(initGroup);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [[WKApp shared].loginInfo load];
        dispatch_group_leave(initGroup);
    });
        
    // 等待前置初始化完成后再进行节点检测
    dispatch_group_notify(initGroup, dispatch_get_main_queue(), ^{
        // 加载本地测试节点
        NSArray<WKServerNode *> *localTestNodes = [self loadLocalTestNodes];
        if (LOCAL_TEST_NODES_NO) {
            NSLog(@"已加载本地测试节点，共%lu个", (unsigned long)localTestNodes.count);
            self.serverNodes = localTestNodes;
            
            // 本地测试节点
            [self checkAndSwitchServerNode:^{
                [self setupAppConfig];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self completeAppInitialization];
                });
            }];
        } else {
            // 获取远程节点列表
            [self fetchServerNodesWithCompletion:^(BOOL success) {
                if (success) {
                    NSLog(@"节点列表获取成功，共%lu个节点", (unsigned long)self.serverNodes.count);
                } else {
                    NSLog(@"节点列表获取失败，使用默认节点");
                    // 若获取失败，用默认节点初始化列表
                    self.serverNodes = @[[WKServerNode nodeWithDict:@{@"url": DEFAULT_SERVER_IP, @"https": @(DEFAULT_HTTPS_ON)}]];
                }
                // 2. 检测并选择可用节点
                [self checkAndSwitchServerNode:^{
                    // 3. 初始化App配置
                    [self setupAppConfig];
                    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [self completeAppInitialization];
                    });
                }];
            }];
        }
    });

    return YES;
}

// 加载本地测试节点配置
- (NSArray<WKServerNode *> *)loadLocalTestNodes {
    // 查找本地JSON文件
    NSString *filePath = [[NSBundle mainBundle] pathForResource:LOCAL_TEST_NODES_FILENAME ofType:@"json"];
    if (!filePath) {
        NSLog(@"本地测试节点文件不存在: %@.json", LOCAL_TEST_NODES_FILENAME);
        return nil;
    }
    
    // 读取文件内容
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    if (!data) {
        NSLog(@"读取本地测试节点文件失败");
        return nil;
    }
    
    // 解析JSON
    NSError *error;
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
    if (error || !json) {
        NSLog(@"解析本地测试节点文件失败: %@", error.localizedDescription);
        return nil;
    }
    
    // 转换为ServerNode数组
    NSMutableArray *nodes = [NSMutableArray array];
    
    // 处理主服务器
    NSDictionary *mainService = json[@"mainServer"];
    if ([mainService isKindOfClass:[NSDictionary class]]) {
        WKServerNode *node = [WKServerNode nodeWithDict:mainService];
        if (node.ip.length > 0) {
            [nodes addObject:node];
        }
    }
    
    // 处理备用服务器
    for (NSDictionary *dict in json[@"backupServers"]) {
        WKServerNode *node = [WKServerNode nodeWithDict:dict];
        if (node.ip.length > 0) {
            [nodes addObject:node];
        }
    }
    
    return nodes.copy;
}

// 完成应用初始化的后续操作
- (void)completeAppInitialization{
    // 设置首页回调
    [WKApp shared].getHomeViewController = ^UIViewController * _Nonnull{
        WKMainTabController *homeViewController =  [WKMainTabController new];
        return homeViewController;
    };
    
    [[WKApp shared] appInit];
    
    // 适配深色模式
    if (@available(iOS 13.0, *)) {
        if([WKApp shared].config.style == WKSystemStyleDark) {
            self.window.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
        }else{
            self.window.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
        }
    }
}

#pragma mark - 节点获取与切换逻辑

// 从JSON地址获取服务器节点列表，带2秒超时
- (void)fetchServerNodesWithCompletion:(void(^)(BOOL success))completion {
    NSURL *url = [NSURL URLWithString:SERVER_NODE_URL];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.timeoutInterval = NODE_FETCH_TIMEOUT; // 设置2秒超时
    
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    config.timeoutIntervalForRequest = NODE_FETCH_TIMEOUT;
    config.timeoutIntervalForResource = NODE_FETCH_TIMEOUT;
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
    
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error || !data) {
            NSLog(@"节点列表请求失败: %@", error.localizedDescription);
            completion(NO);
            return;
        }
        
        // 解析JSON（假设格式为：{"servers":[{"ip":"xxx","https":true},...]}）
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (error || !json) {
            NSLog(@"节点列表解析失败: %@", error.localizedDescription);
            completion(NO);
            return;
        }
        
        // 转换为ServerNode数组
        NSMutableArray *nodes = [NSMutableArray array];
        NSDictionary *mainService = json[@"mainServer"];
        //添加主域名
        if ([mainService isKindOfClass:[NSDictionary class]]){
            WKServerNode *node = [WKServerNode nodeWithDict:mainService];
            if (node.ip.length > 0) { // 过滤无效节点
                [nodes addObject:node];
            }
        }
        //添加节点
        for (NSDictionary *dict in json[@"backupServers"]) {
            WKServerNode *node = [WKServerNode nodeWithDict:dict];
            if (node.ip.length > 0) { // 过滤无效节点
                [nodes addObject:node];
            }
        }
        
        self.serverNodes = nodes.copy;
        completion(YES);
    }];
    [task resume];
}

// 检测主域名可用性，不可用时切换节点（优化超时时间）
- (void)checkAndSwitchServerNode:(void(^)(void))completion {
    // 优先尝试默认主节点
    WKServerNode *defaultNode = [WKServerNode new];
    defaultNode.ip = DEFAULT_SERVER_IP;
    defaultNode.https = DEFAULT_HTTPS_ON;
    // 检测默认节点是否可用（缩短超时时间至2秒）
    [self checkNodeAvailability:defaultNode timeout:2 completion:^(BOOL available) {
        if (available) {
            self.currentServerIP = defaultNode.ip;
            self.currentHTTPSOn = defaultNode.https;
            completion();
            return;
        }
        
        // 默认节点不可用，遍历备用节点
        [self tryNextNodeWithIndex:0 completion:^(BOOL found) {
            if (found) {
                completion();
            } else {
                // 所有节点都不可用，仍使用默认节点（或提示用户）
                self.currentServerIP = defaultNode.ip;
                self.currentHTTPSOn = defaultNode.https;
                NSLog(@"所有节点均不可用，使用默认节点");
                completion();
            }
        }];
    }];
}

// 递归尝试下一个节点
- (void)tryNextNodeWithIndex:(NSInteger)index completion:(void(^)(BOOL found))completion {
    if (index >= self.serverNodes.count) {
        completion(NO);
        return;
    }
    
    WKServerNode *node = self.serverNodes[index];
    [self checkNodeAvailability:node timeout:2 completion:^(BOOL available) {
        if (available) {
            self.currentServerIP = node.ip;
            self.currentHTTPSOn = node.https;
            NSLog(@"切换至节点：%@（HTTPS：%@）当前index %ld", node.ip, node.https ? @"开启" : @"关闭",index);
            completion(YES);
        } else {
            [self tryNextNodeWithIndex:index + 1 completion:completion];
        }
    }];
}

// 检测节点是否可用（增加超时参数控制）
- (void)checkNodeAvailability:(WKServerNode *)node timeout:(NSTimeInterval)timeout completion:(void(^)(BOOL available))completion {
    if (!node || !node.ip.length) {
        completion(NO);
        return;
    }
    
    NSString *scheme = node.https ? @"https" : @"http";
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/v1/", scheme, node.ip]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"HEAD"; // HEAD请求仅获取响应头，速度更快
    request.timeoutInterval = timeout;
    
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    config.timeoutIntervalForRequest = timeout;
    config.timeoutIntervalForResource = timeout;
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
    
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
        BOOL available = false;
        if (!error){
            available = YES;
        }
        completion(available);
    }];
    [task resume];
}

// 初始化App配置（使用当前选中的节点）
- (void)setupAppConfig {
    NSString *baseURL = [NSString stringWithFormat:@"%@://%@/v1/", self.currentHTTPSOn ? @"https" : @"http", self.currentServerIP];
    NSString *webURL = [NSString stringWithFormat:@"%@://%@/web/", self.currentHTTPSOn ? @"https" : @"http", self.currentServerIP];
    
    WKAppConfig *config = [WKAppConfig new];
    config.apiBaseUrl = baseURL;                // api地址
    config.fileBaseUrl = baseURL;               // 文件上传地址
    config.fileBrowseUrl = baseURL;             // 文件预览地址
    config.imageBrowseUrl = baseURL;            // 图片预览地址
    config.reportUrl = [NSString stringWithFormat:@"%@report/html", baseURL]; // 举报地址
    config.privacyAgreementUrl = [NSString stringWithFormat:@"%@privacy_policy.html", webURL]; // 隐私协议
    config.userAgreementUrl = [NSString stringWithFormat:@"%@user_agreement.html", webURL]; // 用户协议
    config.serverNodes = self.serverNodes;
    config.currentServerIP = self.currentServerIP;
    config.currentHTTPSOn = self.currentHTTPSOn;
    [WKApp shared].config = config;
}

#pragma mark - 原有生命周期方法

-(void) applicationWillEnterForeground:(UIApplication *)application {
    NSInteger lastCheckUpdateTime = [[NSUserDefaults standardUserDefaults] integerForKey:@"lastCheckUpdateTime"];
    if(lastCheckUpdateTime == 0) {
        [self checkAppVersionOrUpdate];
    }else if ([[NSDate date] timeIntervalSince1970] - lastCheckUpdateTime > 60.0f * 30.0f){
        [self checkAppVersionOrUpdate];
    }
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    NSLog(@"内存警告");
}

-(void) checkAppVersionOrUpdate {
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *appVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
    [[WKAPIClient sharedClient] GET:[NSString stringWithFormat:@"common/appversion/iOS/%@",appVersion] parameters:nil].then(^(NSDictionary *resultDict){
        [[NSUserDefaults standardUserDefaults] setInteger:[[NSDate date] timeIntervalSince1970] forKey:@"lastCheckUpdateTime"];
        NSString *version = resultDict[@"app_version"];
        if(!version||[version isEqualToString:@""]) {
            [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"lastAlertUpdateTime"];
            return;
        }
        
        if([self versionStrToInt:version]>[self versionStrToInt:appVersion]) {
            NSString  *updateDesc = resultDict[@"update_desc"];
            BOOL isForce = resultDict[@"is_force"]?[resultDict[@"is_force"] boolValue]:false;
            NSString *downloadURL = resultDict[@"download_url"];
            
            [SELUpdateAlert showUpdateAlertWithVersion:resultDict[@"app_version"] Description:updateDesc downloadURL:downloadURL forceUpdate:isForce];
        }
      
    });
}

-(NSInteger) versionStrToInt:(NSString*)versionStr {
    return [[versionStr stringByReplacingOccurrencesOfString:@"." withString:@""] integerValue];;
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    if (!deviceToken || ![deviceToken isKindOfClass:[NSData class]] || deviceToken.length==0) {
        return;
    }
    NSString *(^getDeviceToken)(void) = ^() {
            if (@available(iOS 13.0, *)) {
                const unsigned char *dataBuffer = (const unsigned char *)deviceToken.bytes;
                NSMutableString *myToken  = [NSMutableString stringWithCapacity:(deviceToken.length * 2)];
                for (int i = 0; i < deviceToken.length; i++) {
                    [myToken appendFormat:@"%02x", dataBuffer[i]];
                }
                return (NSString *)[myToken copy];
            } else {
                NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"<>"];
                NSString *myToken = [[deviceToken description] stringByTrimmingCharactersInSet:characterSet];
                return [myToken stringByReplacingOccurrencesOfString:@" " withString:@""];
            }
        };
    NSString *myToken = getDeviceToken();
    NSLog(@"myToken----------->%@",myToken);
    [WKApp shared].loginInfo.deviceToken = myToken;
    [[WKApp shared].loginInfo save];
   NSString *bundleID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
    [[WKAPIClient sharedClient] POST:@"user/device_token" parameters:@{@"device_token":myToken,@"device_type":@"IOS",@"bundle_id":bundleID}].catch(^(NSError *error){
        WKLogError(@"上传设备token失败！-> %@",error);
    });
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    NSLog(@"didReceiveRemoteNotification------>");
    [WKApp.shared application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    WKLogError(@"注册远程通知失败->%@",error);
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    return [[WKApp shared] appOpenURL:url options:options];
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
    return [[WKApp shared] appContinueUserActivity:userActivity restorationHandler:restorationHandler];
}

@end
